/**   
 * @Title: DisplayDpConfigController.java
 * @Package cn.edu.sjtu.se.dslab.controller
 * @Description: TODO(用一句话描述该文件做什么)
 * @author Thinker
 * @date 2013-8-10 下午4:59:47
 * @version V1.0
 */ 
package cn.edu.sjtu.se.dslab.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import cn.edu.sjtu.se.dslab.component.data.DomainEntity;
import cn.edu.sjtu.se.dslab.component.design.DesignPatternComponent;
import cn.edu.sjtu.se.dslab.component.design.DesignPatternType;
import cn.edu.sjtu.se.dslab.component.dp.parse.DesignPatternInstanceBean;
import cn.edu.sjtu.se.dslab.component.dp.parse.Property;
import cn.edu.sjtu.se.dslab.dao.IDisplayZoneDao;
import cn.edu.sjtu.se.dslab.project.DisplayZone;
import cn.edu.sjtu.se.dslab.project.Project;
import cn.edu.sjtu.se.dslab.service.IDesignPatternComponentService;
import cn.edu.sjtu.se.dslab.service.IDisplayZoneService;
import cn.edu.sjtu.se.dslab.service.IDomainEntityService;
import cn.edu.sjtu.se.dslab.service.IInterfaceMethodService;
import cn.edu.sjtu.se.dslab.service.IMethodComponentService;
import cn.edu.sjtu.se.dslab.service.IProjectService;
import cn.edu.sjtu.se.dslab.util.FileUtil;

/** 
 * @ClassName: DisplayDpConfigController
 * @Description: 用于配置显示控制设计模式
 * @author longshaohang
 * @date 2013-8-10 下午4:59:47
 * 
 */
@Controller
public class DisplayDpConfigController {
	
	private static final Logger logger = Logger.getLogger(DisplayDpConfigController.class);

	@Resource(name="designPatternComponentService")
	IDesignPatternComponentService designPatternComponentService;

	@Resource(name="projectService")
	IProjectService projectService;

	@Resource(name="domainEntityService")
	IDomainEntityService domainEntityService;
	
	@Resource(name="displayZoneService")
	IDisplayZoneService displayZoneService;
	
	@Resource(name = "methodComponentService")
	IMethodComponentService methodComponentService;

	@Resource(name = "interfaceMethodService")
	IInterfaceMethodService interfaceMethodService;
	

	@RequestMapping(value = "/displayDesignPattern/{type}/arinc661/add", method = RequestMethod.POST)
	public String addArincPage(@PathVariable(value="type")String type,@RequestParam String pageName, @RequestParam String connections,
			@RequestParam String dpcUri, @RequestParam long projectId,
			@RequestParam String pageType, HttpServletRequest request,
			@RequestParam MultipartFile scadeFile, @RequestParam MultipartFile imageFile)
					throws IOException {
		// 如果只是上传一个文件，则只需要MultipartFile类型接收文件即可，而且无需显式指定@RequestParam注解
		// 如果想上传多个文件，那么这里就要用MultipartFile[]类型来接收文件，并且还要指定@RequestParam注解
		// 并且上传多个文件时，前台表单中的的所有<input
		// type="file"/>的name都应该是myfiles,否则参数里的myfiles无法获取到所有的上传文件
		// 构建一个存放目录
		Project project = projectService.getProjectById(projectId);
		Map<String, String> propertyMap = new HashMap<String, String>();
		propertyMap.put("page_name", pageName);
		propertyMap.put("page_connections", connections);
		propertyMap.put("page_type",pageType );
		//propertyMap.put("display_frequency", displayFrequency);
		
		String realPath = request.getSession().getServletContext().getRealPath("/");
		logger.info(realPath);

		String scadeDir = "img/upload/" + project.getName() + "/";
		FileUtil.createDirectorys(scadeDir);
		String fileName = FileUtil.uploadFile(scadeFile, realPath + scadeDir);
		String imageName = FileUtil.uploadFile(imageFile, realPath + scadeDir);
		propertyMap.put("file_path", scadeDir + fileName);
		propertyMap.put("image_path", scadeDir + imageName);
//
		designPatternComponentService.addDpcItem(propertyMap, dpcUri);
		return toURL(type, projectId);
	}

	@RequestMapping(value = "/displayDesignPattern/{type}/pageData/add", method = RequestMethod.POST)
	public String addPageDataPage(@PathVariable(value="type")String type, @RequestParam String pageName, @RequestParam String[] pageElements,
			@RequestParam String dpcUri, @RequestParam long projectId, @RequestParam String isMain)
			//@RequestParam String pageType,
			//@RequestParam MultipartFile pageFile,@RequestParam MultipartFile imageFile,)
			{
		//Project project = projectService.getProjectById(projectId);
		Map<String, String> propertyMap = new HashMap<String, String>();
		propertyMap.put("page_name", pageName);
		propertyMap.put("is_main", isMain);
		StringBuilder sb = new StringBuilder();
		logger.info(pageElements);
		for (String pe: pageElements){
			logger.info("Add " + pe);
			sb.append(pe).append("|");
		}
		
		propertyMap.put("page_variables", sb.toString());
		propertyMap.put("page_type","pageData" );
		//designPatternComponentService.addDpcItem(propertyMap, dpcUri);
		
		//propertyMap.put("display_frequency", displayFrequency);
		//String realPath = request.getSession().getServletContext().getRealPath("/");
//		logger.info(realPath);
		

//		String pageDir = "img/upload/" + project.getName() + "/";
//		FileUtil.createDirectorys(pageDir);
//		String fileName = FileUtil.uploadFile(pageFile, realPath + pageDir);
//		String imageName = FileUtil.uploadFile(imageFile, realPath + pageDir);
//		propertyMap.put("file_path", pageDir + fileName);
//		propertyMap.put("image_path", pageDir + imageName);
		designPatternComponentService.addDpcItem(propertyMap, dpcUri);
		return toURL(type, projectId);
	}

	@RequestMapping(value = "/displayDesignPattern/{type}/userDefineDF/add", method = RequestMethod.POST)
	public String addSelfDefinePage(@PathVariable(value="type")String type, 
			@RequestParam String pageName, 
			@RequestParam String pageElements,
			@RequestParam String dpcUri, @RequestParam String pageType, @RequestParam String isMain,
			@RequestParam Long projectId) throws IOException {
		Map<String, String> propertyMap = new HashMap<String, String>();
		
//		logger.info(type + "-" + pageName );
//		logger.info(dpcUri);
//		logger.info(pageType);
//		logger.info(isMain);
//		logger.info(projectId);
//		logger.info(pageElements);
		propertyMap.put("page_name", pageName);
		propertyMap.put("page_elements", pageElements);
		propertyMap.put("page_type",pageType );
		propertyMap.put("is_main", isMain);
		
//		if (elements!= null && elements != ""){
//			String[] elementArray = elements.split("\\|");
//			List<StaticString> staticPageELements = new ArrayList<StaticString>();
//			for (String e : elementArray) {
//				PageElement pe = PageElementParseUtil.parsePageElement(e);
//				if (pe != null) {
//					if (pe.getElementType() == ElementType.STATIC_STRING) {
//						elementService.addElement(pe);
//					}
//				}
//			}
//		} 
		
		designPatternComponentService.addDpcItem(propertyMap, dpcUri);
		return toURL(type, projectId);
	}


	// @RequestMapping(value = "/displayDesignPattern/{type}/delete", method =
	// RequestMethod.POST)
	// public String deleteMethodComponent(@PathVariable(value="type")String
	// type, @RequestParam String name,
	@RequestMapping(value = "/displayDesignPattern/delete", method = RequestMethod.POST)
	@ResponseBody
	public Map<String,String> deleteMethodComponent(@RequestParam String name,
			@RequestParam String value, @RequestParam String dpcUri, @RequestParam long projectId){
		Map<String, String> resultMap = new HashMap<String,String>();
		try{
			DesignPatternComponent component = designPatternComponentService.getDesignPatternComponentByUri(dpcUri);
			DesignPatternInstanceBean dpiBean = new DesignPatternInstanceBean(DesignPatternType.DISPLAY, 
				component.getXmlPath());
			dpiBean.deleteInstanceByName(name,value);
			dpiBean.save(component.getXmlPath());

			resultMap.put("result", Boolean.TRUE.toString());
		}catch(Exception ex){
			resultMap.put("result", Boolean.FALSE.toString());
		}
		return resultMap;
//		return toURL(type, projectId);
	}

	@RequestMapping(value = "/displayDesignPattern/info", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, String> getDesignPatternComponentPropertyInfo(@RequestBody LinkedHashMap<String, String> jsonStrings){
		DesignPatternInstanceBean dpiBean =  designPatternComponentService.getDesignPatternInstanceBean(jsonStrings.get("dpcUri"));
		Map<String, Property> instance = dpiBean.getInstanceByName("id", jsonStrings.get("id"));
		Map<String, String> pageMap = new HashMap<String, String>();
		String pageType = jsonStrings.get("pageType");

		pageMap.put("page_name_info", instance.get("page_name").getValue());
		pageMap.put("page_type_info", instance.get("page_type").getValue());
		//pageMap.put("display_frequency_info", instance.get("display_frequency").getValue());
		if ("arinc661".equals(pageType)){
			pageMap.put("scade_file_info", instance.get("file_path").getValue());
			pageMap.put("scade_image_info", instance.get("image_path").getValue());
			pageMap.put("connections_info", instance.get("page_connections").getValue());
		}else if ("userDefineDF".equals(pageType)){
			pageMap.put("elements_info", instance.get("page_elements").getValue());
//			
//			String elements = instance.get("page_elements").getValue();
//			if (elements!= null && elements != ""){
//			String[] elementArray = elements.split("\\|");
//			List<StaticString> staticPageELements = new ArrayList<StaticString>();
//			for (String e : elementArray) {
//				PageElement pe = PageElementParseUtil.parsePageElement(e);
//				if (pe != null) {
//					if (pe.getElementType() == ElementType.STATIC_STRING) {
//						staticPageELements.add((StaticString) pe);
//					}
//				}
//			}
//			pageMap.put("page_elements_info", );
			
			
		}else if ("pageData".equals(pageType)){
			//pageMap.put("variables_info", instance.get("page_variables").getValue());
			String variablesInfo = instance.get("page_variables").getValue();
			
//			pageMap.put("page_file_info", instance.get("file_path").getValue());
//			pageMap.put("page_image_info", instance.get("image_path").getValue());
//			String variablesString = instance.get("page_variables").getValue();
//			String resultString = instance.get("page_variables").getValue();
			
			//name,displayzone,code,methodComponent
			String[] variables = variablesInfo.split("\\|"); //转义
			int startIndex = 0;
			int endIndex = 0;
			StringBuilder sb = new StringBuilder();
			for (String variable: variables){
				if (variable == null || variable.equals("")) continue;
				//name
    		   	startIndex = 0;
    		   	endIndex = variable.indexOf(';'); //第一个逗号
    		    sb.append(variable.substring(startIndex, endIndex)).append(";");
    		    //displayZone
    		   	startIndex = endIndex+1;
		   		endIndex = variable.indexOf(';',startIndex);
		   		Long displayZoneId = Long.parseLong(variable.substring(startIndex, endIndex));
		   		DisplayZone displayZone = displayZoneService.getDisplayZoneById(displayZoneId);
		   		sb.append(displayZone.getName()).append(";");
		   		//code
		   		startIndex = endIndex+1;
		   		endIndex = variable.indexOf(';',startIndex);
		   		sb.append(variable.substring(startIndex, endIndex)).append(";");
		   		//method
		   		startIndex = endIndex + 1;
		   		String methodComponent = variable.substring(startIndex);
		   		int i = variable.indexOf(';', startIndex);
		   		String uri = variable.substring(i+1);
		   		logger.info(uri);
		   		
		   		String methodSigniture = interfaceMethodService
						.getInterfaceMethodById(Long.parseLong(variable.substring(startIndex, i)))
						.getMethodSigniture();
				String methodComponentName = methodComponentService
						.getMethodComponentByUri(uri).getName();
		   		sb.append(methodSigniture).append("--").append(methodComponentName).append("|");
		   		
		   		
		   		
				
//    		   	if (variable.contains("variable_type:data_entity")){
////					startIndex = variablesString.indexOf("variable_value", offset) + "variable_value".length() + 1;
////					endIndex = variablesString.indexOf("|", startIndex);
////					String uri = variablesString.substring(startIndex, endIndex);
////					DomainEntity domainEntity = domainEntityService.getDomainEntityByUri(uri);
////					if (domainEntity!=null){
////						resultString = resultString.replace(uri, domainEntity.getName());
////					}
//				}
//				offset += (variable.length() + 1);
			}
//			pageMap.put("variables_info", resultString);
			pageMap.put("variables_info", sb.toString());
		}

		pageMap.put("success", "true");
		return pageMap;
	}
	
	@RequestMapping(value = "/displayDesignPattern/scadeFile", method = RequestMethod.GET)
	public void getScadeFile(@RequestParam String filePath, HttpServletRequest request,
			HttpServletResponse response){
		//String actorFilePath = rhapsodyFileService.generateActorFile(projectId);
		try{
			String scadeFilePath = request.getSession().getServletContext().getRealPath("/");
			File scadeFile = new File(scadeFilePath + filePath);
			logger.info("Scade file Path:" + scadeFilePath + filePath);
			InputStream is = new FileInputStream(scadeFile);
			response.setContentType("application/octet-stream");
			response.setContentLength((int) scadeFile.length());
			String headerKey = "Content-Disposition";
			String headerValue = String.format("attachment;filename=\"%s\"",
					scadeFile.getName());
			response.setHeader(headerKey, headerValue);
			IOUtils.copy(is, response.getOutputStream());
			is.close();
			response.flushBuffer();
//			resultMap.put("result", Boolean.TRUE.toString());
		}catch(Exception ex){
//			resultMap.put("result", Boolean.FALSE.toString());
			logger.error(ex.getStackTrace());
		}
	}
	
	private String toURL(String type, long projectId){
		StringBuilder url = new StringBuilder("redirect:/");
		url.append(type).append("/").append(projectId).append("/design_pattern_component/DISPLAY/edit");
		return url.toString();
	}
}


